﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using DDW;
using UIDesigner.FieldHandlers;
using System.Drawing;
using System.Windows.Forms;
using UIDesigner.FieldHandlers.Bases;
using System.ComponentModel.Design.Serialization;

namespace UIDesigner.ControlProviders.Bases
{
    public abstract class BaseControlProvider : IControlProvider
    {
        protected AFDesignerHost m_objHost;

        public abstract void AddBindings(Control ctrlBinding, BaseNode objBase, string strBindingSourceProperty);
        public abstract Control AddControls(string strOption, IComponent ctrlParent, BaseNode objBase, bool bDefault, bool bPreview, int nTabIndex, List<Rectangle> rgLocationRects, List<char> rgMnemonics);
        public abstract Control AddControls(string strOption, TableLayoutPanel ctrlParent, BaseNode objBase, bool bDefault, bool bPreview, int nTabIndex, List<TableLayoutPanelCellPosition> rgTableLayoutPanelCellPositions, List<char> rgMnemonics);
        public abstract void NegotiateLayout(string strOption, IComponent ctrlParent, BaseNode objBase, LayoutMode eLayoutMode, ref int nTabIndex, out LayoutStyle eLayoutStyle, out int nLabelAlignment, out Size szControlSize);

        public BaseControlProvider(AFDesignerHost objHost)
        {
            m_objHost = objHost;
        }

        public virtual bool SupportsOption(string strOption)
        {
            foreach (Attribute objAttr in this.GetType().GetCustomAttributes(true))
            {
                ControlProviderAttribute objProviderAttr = objAttr as ControlProviderAttribute;

                if (objProviderAttr != null)
                {
                    if (objProviderAttr.SupportedOptions.Contains<string>(strOption))
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        protected BindingSource GetBindingSource(string strBindingSourceProperty)
        {
            foreach (IComponent objComponent in m_objHost.Container.Components)
            {
                if (objComponent.Site.Name == strBindingSourceProperty)
                {
                    return (BindingSource) objComponent;
                }
            }

            return (BindingSource) m_objHost.CreateComponent(typeof(BindingSource), strBindingSourceProperty);
        }

        protected string HandleName(string strName)
        {
            string strNewName = m_objHost.HandleName(strName);
            return strNewName;
        }

        protected string HandleName(BaseNode objBase)
        {
            if (objBase is ParamDeclNode)
            {
                PredefinedTypeNode objType = objBase.Type as PredefinedTypeNode;
                string strPrefix;
                string strName;

                if (objType != null)
                {
                    strPrefix = BaseFieldHandler.GetVariablePrefix(objType.Identifier.GenericIdentifier);
                }
                else
                {
                    strPrefix = BaseFieldHandler.GetVariablePrefix("object");
                }

                if (objBase.Name.StartsWith(strPrefix))
                {
                    strName = objBase.Name.Substring(strPrefix.Length);

                    return strName;
                }
            }

            return objBase.Name;
        }

        protected string HandleMnemonics(string strName, List<char> rgMnemonics)
        {
            int nIndex = 0;
            char ch = strName[0];
            string strNewName = null;

            while (rgMnemonics.Contains(ch))
            {
                nIndex++;

                if (nIndex >= strName.Length)
                {
                    return strName;
                }

                ch = strName[nIndex];
            }

            rgMnemonics.Add(ch);
            strNewName = strName.Substring(0, nIndex) + "&" + strName.Substring(nIndex, strName.Length - nIndex);

            return strNewName;
        }

        protected static string GetControlPrefix(Type objType)
        {
            string strName = objType.Name;
            string strPrefix = null;

            while (strPrefix == null)
            {
                switch (strName)
                {
                    case "CheckBox":
                        strPrefix = "chk";
                        break;
                    case "CheckedListBox":
                        strPrefix = "lst";
                        break;
                    case "ComboBox":
                        strPrefix = "cbo";
                        break;
                    case "Control":
                        strPrefix = "ctrl";
                        break;
                    case "DomainUpDown":
                        strPrefix = "txt";
                        break;
                    case "Form":
                        strPrefix = "frm";
                        break;
                    case "Label":
                        strPrefix = "lbl";
                        break;
                    case "ListBox":
                        strPrefix = "lst";
                        break;
                    case "ListViewContainer":
                        strPrefix = "lst";
                        break;
                    case "MaskedTextBox":
                        strPrefix = "txt";
                        break;
                    case "NumericUpDown":
                        strPrefix = "txt";
                        break;
                    case "OrderedListBox":
                        strPrefix = "lst";
                        break;
                    case "OrderedListView":
                        strPrefix = "lst";
                        break;
                    case "RichTextBox":
                        strPrefix = "txt";
                        break;
                    case "SerialCode":
                        strPrefix = "txt";
                        break;
                    case "StateDropdown":
                        strPrefix = "cbo";
                        break;
                    case "SubForm":
                        strPrefix = "ctrl";
                        break;
                    case "TextBox":
                        strPrefix = "txt";
                        break;
                    case "TimeDropDown":
                        strPrefix = "cbo";
                        break;
                    default:
                        objType = objType.BaseType;
                        strName = objType.Name;
                        break;
                }
            }

            return strPrefix;
        }

        protected static bool HasGetter(BaseNode objBase)
        {
            return BaseFieldHandler.HasGetter(objBase);
        }

        protected static bool HasSetter(BaseNode objBase)
        {
            return BaseFieldHandler.HasSetter(objBase);
        }

        protected static string GetPrettyName(BaseNode objBase)
        {
            return BaseFieldHandler.GetPrettyName(objBase);
        }

        protected static string GetPrettyDescription(BaseNode objBase)
        {
            return BaseFieldHandler.GetPrettyDescription(objBase);
        }

        public static bool IsReadOnlyResult(BaseNode objBase)
        {
            return BaseFieldHandler.IsReadOnlyResult(objBase);
        }

        public static bool IsWriteOnlyResult(BaseNode objBase)
        {
            return BaseFieldHandler.IsWriteOnlyResult(objBase);
        }
    }
}
